package sys_ctrl

import (
	"ubt-gin-admin/app/api/model/sys_mod"
	"ubt-gin-admin/app/api/service/sys_serv"
	"ubt-gin-admin/app/pkg/enums"
	"ubt-gin-admin/app/pkg/parse"
	"ubt-gin-admin/app/utils"

	"github.com/gin-gonic/gin"
)

type sysMenu struct{}

var SysMenuCtrl sysMenu

// Save 保存菜单
func (c *sysMenu) Save(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	req := &sys_mod.SysMenuSaveReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(ctx, req); err != "" {
		utils.ToJson(ctx, enums.ParamErr.Code, err, nil)
		return
	}
	// 过滤关键参数值中的非法字符
	req.MenuId = utils.InputFilter(req.MenuId, true)
	req.MenuName = utils.InputFilter(req.MenuName, true)
	req.MenuCode = utils.InputFilter(req.MenuCode, true)
	req.ParentId = utils.InputFilter(req.ParentId, true)
	req.Url = utils.InputFilter(req.Url, true)
	req.Icon = utils.InputFilter(req.Icon, true)
	if req.MenuId == req.ParentId {
		utils.ToJson(ctx, enums.ParentErr.Code, enums.ParentErr.Msg, nil)
		return
	}
	// 判断编码是否重复
	extVo := &sys_mod.SysMenuExtVo{MenuId: req.MenuId, MenuCode: req.MenuCode}
	if ext := sys_serv.SysMenuServ.Exists(extVo); ext {
		utils.ToJson(ctx, enums.ExistsErr.Code, enums.ExistsErr.Msg, nil)
		return
	}
	var (
		code string
		msg  string
		kind uint8
	)
	if req.MenuId == "" {
		// 新增
		code, msg = sys_serv.SysMenuServ.Add(req)
		kind = 1
	} else {
		// 修改
		code, msg = sys_serv.SysMenuServ.Update(req)
		kind = 3
	}
	if code == enums.Succeed.Code {
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, MenuCode: enums.SysMenu, IpAddr: userInfo.ClientIp, Kind: kind}
		sys_serv.SysLogServ.Add(logReq)
	}
	utils.ToJson(ctx, code, msg, nil)
}

// Deletes 删除菜单
func (c *sysMenu) Deletes(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	// 将请求的参数转换为请求结构体
	req := &sys_mod.SysMenuDelsReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(ctx, req); err != "" {
		utils.ToJson(ctx, enums.ParamErr.Code, err, nil)
		return
	}
	// 过滤关键参数值中的非法字符
	req.MenuIds = utils.InputFilter(req.MenuIds, true)
	code, msg := sys_serv.SysMenuServ.Deletes(req)
	if code == enums.Succeed.Code {
		// 同时删除菜单下的按钮数据
		ch := make(chan int)
		go sys_serv.SysBtnServ.DelByMenu(ch, req.MenuIds)
		ch <- 1
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, MenuCode: enums.SysMenu, IpAddr: userInfo.ClientIp, Kind: 2}
		sys_serv.SysLogServ.Add(logReq)
	}
	utils.ToJson(ctx, code, msg, nil)
}

// One 获取菜单详情
func (c *sysMenu) One(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	// 过滤关键参数值中的非法字符
	menuId := ctx.Query("menuId")
	menuId = utils.InputFilter(menuId, true)
	if menuId == "" || len(menuId) != 21 {
		utils.ToJson(ctx, enums.ParamErr.Code, enums.ParamErr.Msg, nil)
		return
	}
	code, msg, data := sys_serv.SysMenuServ.One(menuId)
	utils.ToJson(ctx, code, msg, data)
}

// List 获取菜单树状列表
func (c *sysMenu) List(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	code, msg, data := sys_serv.SysMenuServ.List()
	utils.ToJson(ctx, code, msg, data)
}

// Tree 获取菜单树状列表
func (c *sysMenu) Tree(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	code, msg, data := sys_serv.SysMenuServ.Tree()
	utils.ToJson(ctx, code, msg, data)
}

// Menu 获取菜单菜单树状菜单
func (c *sysMenu) Menu(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	menuCodes := userInfo.MenuCodes
	code, msg, data := sys_serv.SysMenuServ.Menu(menuCodes)
	utils.ToJson(ctx, code, msg, data)
}

// Select 获取树状菜单及按钮的列表
func (c *sysMenu) Select(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	code, msg, data := sys_serv.SysMenuServ.Select(userInfo.MenuCodes, userInfo.Kind)
	if code == enums.Succeed.Code {
		menuList := data.([]map[string]any)
		if code2, _, data2 := sys_serv.SysBtnServ.Select(); code2 == enums.Succeed.Code {
			allBtnList := data2.([]*sys_mod.SysBtnSelRes)
			for _, curMenu := range menuList {
				var btnList []*sys_mod.SysBtnSelRes
				for _, curBtn := range allBtnList {
					if curMenu["menuId"] == curBtn.MenuId {
						btnList = append(btnList, curBtn)
					}
				}
				curMenu["btnList"] = btnList
			}
		}
	}
	utils.ToJson(ctx, code, msg, data)
}

// Sort 获取菜单数量，用于排序
func (c *sysMenu) Sort(ctx *gin.Context) {
	// 通过头部请求的token获取用户信息
	token := ctx.GetHeader("token")
	userInfo := utils.GetUserInfo(ctx, token)
	if userInfo == nil {
		utils.ToJson(ctx, enums.NoLoginErr.Code, enums.NoLoginErr.Msg, nil)
		return
	}
	parentId := ctx.Query("parentId")
	parentId = utils.InputFilter(parentId, true)
	if parentId == "" || len(parentId) != 21 {
		utils.ToJson(ctx, enums.ParamErr.Code, enums.ParamErr.Msg, nil)
		return
	}
	code, msg, data := sys_serv.SysMenuServ.Sort(parentId)
	utils.ToJson(ctx, code, msg, data["nums"])
}
